<?php

/**
 * 新闻管理
 */

namespace app\admin\service;

use app\admin\model\MarketSmCopywritingTasks as MarketSmCopywritingTasksModel;
use app\common\RedisClient;
use think\Service;
use app\admin\model\CryptoNews as CryptoNewsModel;
use app\admin\model\MarketNewsSearchDet as MarketNewsSearchDetModel;
use app\admin\model\MarketSmCopywriting as CryptoNewsPublishInfoModel;
use app\admin\model\MarketSocialMediaAccountGroup as MarketSocialMediaAccountGroupModel;
use app\admin\model\Images as ImagesModel;
use app\admin\model\SystemLanguage as SystemLanguageModel;
use app\common\ApiClient;
use think\facade\Queue;

class CryptoNews extends BaseService
{

    /**
     * 获取新闻列表
     * @param $param
     * @param $page
     * @param $limit
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-10-23 15:27:57
     * author: jiang
     */
    public function getList($param = [], $page = 1, $limit = 10)
    {
        $arrData = ['code' => 0, 'message' => 'success'];
        $where = [];
        if ($param['title_cn']) {
            $where[] = ['title_cn', 'like', '%' . $param['title_cn'] . '%'];
        }
        if ($param['source']) {
            $where[] = ['source', 'like', '%' . $param['source'] . '%'];
        }

        if ($param['start_date']) {
            $where[] = ['time', '>=', $param['start_date']];
        }
        if ($param['end_date']) {
            $where[] = ['time', '<', $param['end_date']];
        }

        $oCryptoNewsModel = CryptoNewsModel::where($where);
        $total = $oCryptoNewsModel->count();
        $result = $oCryptoNewsModel->page($page, $limit)->order('time', 'desc')->select();
        $arrData['data'] = ['list' => $result->toArray(), 'total' => $total];
        return $arrData;
    }

    /**
     * 获取单条数据
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-10-23 15:28:11
     * author: jiang
     */
    public function getInfo($param)
    {
        $where = [['id', '=', $param['id']]];
        $oCryptoNewsModel = CryptoNewsModel::where($where)->with(['publish'])->find();
        $oCryptoNewsModel->news_search_det = extractListFromData($this->searchNews($param));
        $oCryptoNewsModel->copywriting_tasks = MarketSmCopywritingTasksModel::with(['crypto_news'])->where('crypto_news_id', $param['id'])->order('id desc')->select();
        foreach ($oCryptoNewsModel->copywriting_tasks as &$item) {
            if ($item->imgs) {
                $img_arr = explode(',', $item->imgs);
                $oImages = new ImagesModel();
                $item->imgs = $oImages->getImagesByIds($img_arr);
            } else {
                $item->imgs = [];
            }
        }
        if (!$oCryptoNewsModel) {
            return ['code' => 1, 'message' => '获取新闻信息失败！'];
        }
        return ['code' => 0, 'message' => 'success', 'data' => $oCryptoNewsModel];
    }

    /**
     * 批量修改状态
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-10-23 15:28:34
     * author: jiang
     */
    public function status($param)
    {
        $result = CryptoNewsPublishInfoModel::whereIn('id', $param['ids'])->update([
            'status' => $param['status'],
            'update_time' => date('Y-m-d H:i:s'),
            'updater' => $param['operator_id']
        ]);
        if (!$result) {
            return ['code' => 1, 'message' => '操作失败！'];
        }
        return ['code' => 0, 'message' => '操作成功！'];
    }

    /**
     * 新闻发布/更新
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-10-23 15:28:47
     * author: jiang
     */
    public function publish($param)
    {
        if (!$param['associatedMiners']) {
            $miner_name = '';
            $miner_description = '';
            $mining_machine = '';
        } else {
            $miner_arr = json_decode($param['associatedMiners'], true);
            if ($miner_arr && isset($miner_arr['name'])) {
                $miner_name = $miner_arr['name'];
                $miner_description = sprintf(
                    "%s Algorithm: %s Mineable coin: %s Profit per day: %s",
                    $miner_name,
                    $miner_arr['algorythm'] ?? '',
                    $miner_arr['minable_coin'] ?? '',
                    $miner_arr['income_day'] ?? ''
                );
                $mining_machine = $miner_arr['pid'];
            } else {
                $miner_name = '';
                $miner_description = '';
                $mining_machine = '';
            }
        }

        $content = [];
        $oCryptoNewsModel = CryptoNewsModel::with('market_news_search_det')->where('id', '=', $param['id'])->select();
        foreach ($oCryptoNewsModel as $value) {
            $temp = [
                'id' => $value->id,
                'content' => $value->content,
                'miner_name' => $miner_name,
                'miner_description' => $miner_description
            ];
            if ($value->market_news_search_det) {
                foreach ($value->market_news_search_det as $v) {
                    $temp['search_results'][] = $v->content;
                }
            }
            $content[] = $temp;
        }

        $apiClient = new ApiClient('https://func-jecha-ycfdxzguxv.us-west-1.fcapp.run');

        // 获取语言
        $enum = [];
        $oSystemLanguage = SystemLanguageModel::where('status', 1)->where('is_del', 0)->column('id,english_name as name');
        foreach ($oSystemLanguage as $lang) {
            $enum[$lang['id']] = $lang['name'];
        }
        if (!isset($enum[$param['language']])) {
            return ['code' => 1, 'message' => '语言类型错误！'];
        }

        $response = $apiClient->post('/', [
            'body' => json_encode([
                'platform' => $param['platform'],
                'prompt' => $param['cue_word'],
                'target_language' => $enum[$param['language']],
                'contents' => $content
            ])
        ]);
        $operation_data = [];
        if (0 == $response['status'] && $response['body']['response']) {
            foreach ($response['body']['response'] as $item) {
                $temp = [
                    'platform' => $param['platform'],
                    'cue_word' => $param['cue_word'],
                    'crypto_news_id' => $item['id'],
                    'content' => $item['content'],
                    'mining_machine' => $mining_machine,
                    'language' => $param['language'],
                    'status' => 0
                ];
                $operation_data[] = $temp;
            }
        } else {
            return ['code' => 1, 'message' => '生成失败！'];
        }
        $result = CryptoNewsPublishInfoModel::insertAll($operation_data);
        if (!$result) {
            return ['code' => 1, 'message' => '操作失败！'];
        }
        // todo 没有拿到插入后的id
//        $this->logger->logOperation(121212,'CryptoNews','发布/更新','新闻发布/更新');


        return ['code' => 0, 'message' => '操作成功！'];
    }

    /**
     *
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-11-26 13 52 49
     * author: jiang
     */
    public function publishByQueue($param)
    {
        if (!$param['associatedMiners']) {
            $miner_name = '';
            $miner_description = '';
        } else {
            $miner_arr = json_decode($param['associatedMiners'], true);
            if ($miner_arr && isset($miner_arr['name'])) {
                $miner_name = $miner_arr['name'];
                $miner_description = sprintf(
                    "%s Algorithm: %s Mineable coin: %s Profit per day: %s",
                    $miner_name,
                    $miner_arr['algorythm'] ?? '',
                    $miner_arr['minable_coin'] ?? '',
                    $miner_arr['income_day'] ?? ''
                );
            } else {
                $miner_name = '';
                $miner_description = '';
            }
        }

        $content = [];
        $oCryptoNewsModel = CryptoNewsModel::with('market_news_search_det')->where('id', '=', $param['id'])->select();

        foreach ($oCryptoNewsModel as $value) {
            $temp = [
                'id' => $value->id,
                'content' => $value->content,
                'miner_name' => $miner_name,
                'miner_description' => $miner_description
            ];
            if (0 !== count($value->market_news_search_det)) {
                foreach ($value->market_news_search_det as $v) {
                    $temp['search_results'][] = $v->content;
                }
            } else {
                $temp['search_results'] = [];
            }
            $content[] = $temp;
        }

        $apiClient = new ApiClient('https://func-jecha-ycfdxzguxv.us-west-1.fcapp.run');

        // 获取语言
        $enum = [];
        $oSystemLanguage = SystemLanguageModel::where('status', 1)->where('is_del', 0)->column('id,english_name as name');
        foreach ($oSystemLanguage as $lang) {
            $enum[$lang['id']] = $lang['name'];
        }
        if (!isset($enum[$param['language']])) {
            return ['code' => 1, 'message' => '语言类型错误！'];
        }

        $response = $apiClient->post('/', [
            'body' => json_encode([
                'platform' => $param['platform'],
                'prompt' => $param['cue_word'],
                'target_language' => $enum[$param['language']],
                'contents' => $content
            ])
        ]);
        $oCryptoNewsPublishInfoModel = CryptoNewsPublishInfoModel::find($param['writing_id']);
        if (!$oCryptoNewsPublishInfoModel) {
            return ['code' => 1, 'message' => '操作失败！'];
        }
        $oCryptoNewsPublishInfoModel->execution_time = date('Y-m-d H:i:s', time());

        if (0 == $response['status'] && $response['body']['response']) {
            foreach ($response['body']['response'] as $item) {
                $oCryptoNewsPublishInfoModel->task_status = 1;
                $oCryptoNewsPublishInfoModel->content = $item['content'];
            }
        } else {
            $oCryptoNewsPublishInfoModel->execution_result = $oCryptoNewsPublishInfoModel->execution_result . json_encode($response);
            $oCryptoNewsPublishInfoModel->redo_num = ++$oCryptoNewsPublishInfoModel->redo_num;
            $oCryptoNewsPublishInfoModel->save();
            return ['code' => 1, 'message' => '生成失败！'];
        }
        $result = $oCryptoNewsPublishInfoModel->save();

        if (!$result) {
            return ['code' => 1, 'message' => '操作失败！'];
        }
        $this->logger->logOperation($oCryptoNewsPublishInfoModel->id, 'CryptoNews', '队列发布', '队列发布');
        return ['code' => 0, 'message' => '操作成功！'];
    }

    /**
     * 删除
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-10-23 15:29:07
     * author: jiang
     */
    public function delete($param)
    {
        $oCryptoNewsPublishInfoModel = CryptoNewsPublishInfoModel::where('id', $param['id'])->find();
        if (!$oCryptoNewsPublishInfoModel) {
            return ['code' => 1, 'message' => '未找到数据！'];
        }
        $result = $oCryptoNewsPublishInfoModel->delete();
        if (!$result) {
            return ['code' => 1, 'message' => '删除失败！'];
        } else {
            return ['code' => 0, 'message' => '删除成功！'];
            $this->logger->logOperation($result->id, 'CryptoNews', '删除', '删除社媒文案');
        }
    }

    /**
     * 获取服务器列表
     * @return array
     * 2024-10-23 15:29:31
     * author: jiang
     */
    public function machineList()
    {
        $arrData = ['code' => 0, 'message' => 'success'];

        $redis = new RedisClient();
        $data = $redis->get('miners');
        if (!$data) {
            $apiClient = new ApiClient('https://minetheasic.com/wp-content/themes/neve-child/api');
            $data = $apiClient->post('/social_project.php', [
                'body' => json_encode([])
            ]);
            $redis->set('miners', json_encode($data));
            $redis->setExpiry('miners', 86400);
        } else {
            $data = json_decode($data, true);
        }

        $data = $data ?? [];
        $groupedData = [];

        foreach ($data as &$item) {
            $brand = $item['brand'];
            // 如果品牌不存在于$groupedData中，则添加新条目
            if (!isset($groupedData[$brand])) {
                $groupedData[$brand] = [
                    'brand' => $brand,
                    'children' => []
                ];
            }
            $item['name'] = $item['brand'] . ' ' . $item['name'];
            // 将商品信息添加到对应品牌的children数组中
            array_push($groupedData[$brand]['children'], $item);
        }
        $formatData = [];
        foreach ($groupedData as $key => $value) {
            $brand = [
                'value' => $key,
                'label' => $value['brand']
            ];
            foreach ($value['children'] as $child) {
                $brand['children'][] = [
                    'value' => json_encode($child),
                    'label' => $child['name']
                ];
            }
            $formatData[] = $brand;
        }
        $arrData['data'] = ['list' => $formatData];
        return $arrData;
    }

    /**
     * 智能搜索
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-10-23 15:29:52
     * author: jiang
     */
    public function searchNews($param)
    {
        $arrData = ['code' => 0, 'message' => 'success'];
        $oCryptoNewsModel = CryptoNewsModel::where('id', $param['id'])->find();
        if (!$oCryptoNewsModel) {
            return ['code' => 1, 'message' => '未找到数据！'];
        }
        $where = [['is_del', '=', 0], ['crypto_news_id', '=', $param['id']]];

        $oMarketNewsSearchDetModel = MarketNewsSearchDetModel::where($where)->order('id desc')->select();
        //        if (count($oMarketNewsSearchDetModel) > 0) {
        $arrData['data'] = ['list' => $oMarketNewsSearchDetModel->toArray()];
        return $arrData;
        //        }

        $apiClient = new ApiClient('https://fc-socil-search-lfhljjsytn.us-west-1.fcapp.run');
        $data = $apiClient->post('/', [
            'body' => json_encode([
                'content' => $oCryptoNewsModel->content
            ])
        ]);
        $insert_data = [];
        if ($data['body']) {
            foreach ($data['body'] as $item) {
                $insert_data[] = [
                    'crypto_news_id' => $param['id'],
                    'title' => $item['title'],
                    'keyword' => $item['keyword'],
                    'description' => $item['description'],
                    'content' => $item['content'],
                    'url' => $item['url'],
                    'is_del' => 0,
                    'creator' => $param['operator_id'],
                    'create_time' => date('Y-m-d H:i:s')
                ];
            }
        }
        if (count($insert_data) > 0) {
            MarketNewsSearchDetModel::insertAll($insert_data);
            //todo 获取不到id
//            $this->logger->logOperation('', 'CryptoNews', '智能搜索', '智能搜索');
        }
        $arrData['data'] = ['list' => $insert_data];
        return $arrData;
    }

    /**
     * 获取字段枚举值
     * @param $field
     * @return array
     * 2024-10-23 15:30:05
     * author: jiang
     */
    public function getFieldEnum($field)
    {
        $model = new CryptoNewsModel();
        $res = $model->getFieldEnum($field, function () {
            return $this->machineList();
        });
        $res['account_group'] = MarketSocialMediaAccountGroupModel::where([['status', '=', 1], ['is_del', '=', 0]])->column(['name as label', 'id as value']);
        return [
            'code' => 0,
            'data' => $res
        ];
    }
}
